#include "JBaseFile.h"
#include <boost/filesystem.hpp>
#include "JDir.h"
#include "JFileException.h"
#include "JException.h"
#include "JDefine.h"
#include "JString.h"

using namespace boost::filesystem;

JBaseFile::JBaseFile(void)
{

}

JBaseFile::JBaseFile( std::string _fileName,std::string _createTime,std::string _verifyTime ) : filename(_fileName),createTime(_createTime),verifyTime(_verifyTime)
{

}

JBaseFile::JBaseFile( std::string _fileName ):filename(_fileName)
{

}


JBaseFile::~JBaseFile(void)
{
}

void JBaseFile::FillFileInfo()
{
    this->createTime = "2013年5月16日 12:00:00";
    this->verifyTime = "2013年5月16日 12:00:00";
}



int JBaseFile::Serialize( JInOutPut& _strea,int& allSize )
{
	////Serialize begin.
	//std::string filename;
	//std::string createTime;
	//std::string verifyTime;
	////Serialize end.
	int classSize = 0,selfSize = 0;
	JSerialize::SerializeHead(_strea,selfSize,classSize);
	JSerialize::Serialize(_strea,filename,classSize);
	JSerialize::Serialize(_strea,createTime,classSize);
	JSerialize::Serialize(_strea,verifyTime,classSize);
	return JSerialize::SerializeTail(_strea,allSize,selfSize,classSize);
}

int JBaseFile::ReSerialize( JInOutPut& _strea )
{
	int classSize = JSerialize::ReSerializeHead(_strea);
	this->filename = JSerialize::ReSerializeString(_strea);
	this->createTime = JSerialize::ReSerializeString(_strea);
	this->verifyTime = JSerialize::ReSerializeString(_strea);
        return classSize;
}

        /*到远程服务器，建包*/
int JBaseFile::PackStubMessage(JInOutPut& _strea,int& _allSize)
{
	int classSize = 0,selfSize = 0;
	JSerialize::SerializeHead(_strea,selfSize,classSize);
	JSerialize::Serialize(_strea,filename,classSize);
	JSerialize::Serialize(_strea,createTime,classSize);
	JSerialize::Serialize(_strea,verifyTime,classSize);
	return JSerialize::SerializeTail(_strea,_allSize,selfSize,classSize);
}
        /*服务器解包*/
int JBaseFile::UnPackStubMessage(JInOutPut& _strea)
{
    	int classSize = JSerialize::ReSerializeHead(_strea);
	this->filename = JSerialize::ReSerializeString(_strea);
	this->createTime = JSerialize::ReSerializeString(_strea);
	this->verifyTime = JSerialize::ReSerializeString(_strea);
         return classSize;
}

std::string JBaseFile::Absolute( std::string _fileName )
{
	path p = absolute(_fileName);
	return p.string();
}

bool JBaseFile::HasGenerateFile( std::string ancestor,std::string _fileName )
{
    //如果ancestor="/abc/."这样的目录，需要先去掉最后的.
    if(ancestor.at(ancestor.size()-1) == '.')
    {
        ancestor = ancestor.substr(0,ancestor.size() - 1);
    }
	if((_fileName.find(ancestor) != std::string::npos || _fileName == ancestor) && exists(ancestor))
	{
		return true;
	}
	return false;
}

std::list<std::string> JBaseFile::RecurseDownBaseFile(std::string _rootPath) 
{
    std::list<std::string> listFileName;
    if (exists(_rootPath)) 
    {
        if (is_directory(_rootPath)) 
        {
            listFileName = JDir::RecurseDownDir(_rootPath);
        }
        else 
        {
            listFileName.push_back(_rootPath);
        }
    }
    return listFileName;
}

void JBaseFile::ReName( std::string oldFileName,std::string newFileName )
{
	try
	{
		path p(oldFileName);
		path p2(newFileName);
		rename(p,p2);
	}
	catch(filesystem_error& e)
	{
            throw JFileException(e.what());
	}
	catch(std::exception e)
	{
            throw JFileException(e.what());
	}

}

bool JBaseFile::HasChildBaseFile( std::string parentPath,std::string baseFileName )
{
	if(is_directory(parentPath))
	{
		directory_iterator ite = directory_iterator(parentPath);
		for(;ite != directory_iterator(); ++ite)
		{
			if(ite->path().string() == baseFileName)
			{
				return true;
			}
		}
	}
	return false;
}

bool JBaseFile::IsExist(std::string _path) 
{
    if (exists(_path)) 
    {
        return true;
    }
    return false;
}

bool JBaseFile::CopyBaseFile( std::string oldFileName,std::string newFileName )
{
    //boost::system::error_code ec;
    try
    {
        copy(oldFileName,newFileName);
    }
	catch(boost::exception& e)
    {
	return false;
    }
    return true;
}

bool JBaseFile::IsAncestor(const std::string& _ancestor, const std::string& _fileName)
{
    if(OPERATION_SYSTEM_TYPE == "LINUX")
    {
        std::list<std::string> ancestorFragementPath = JString::StrSplit(_ancestor,PATH_SPLIT);
        std::list<std::string> fragementPath = JString::StrSplit(_fileName,PATH_SPLIT);
        if(ancestorFragementPath.size() >= fragementPath.size())
        {
            return false;
        }
        std::list<std::string>::iterator ancestorIte = ancestorFragementPath.begin();
        std::list<std::string>::iterator pathIte = fragementPath.begin();
        while(ancestorIte != ancestorFragementPath.end())
        {
            if(*ancestorIte != *pathIte)
            {
                return false;
            }
            ++ancestorIte;
            ++pathIte;
        }
        return true;
    }
}

std::list<std::string> JBaseFile::GenerateAncestor(const std::string& p)
{
    if(OPERATION_SYSTEM_TYPE == "LINUX")
    {
        std::list<std::string> datas;
        std::list<std::string> str = JString::StrSplit(p,PATH_SPLIT);
        std::list<std::string>::iterator ite = str.begin();
        std::list<std::string>::iterator iteEnd = str.end();
        --iteEnd;
        std::string tmp = "";
        for(;ite != iteEnd; ++ite)
        {
            tmp += PATH_SPLIT + *ite;
            datas.push_back(tmp);
        }
        return datas;
    }
}

bool JBaseFile::Compare(const std::string& _p1, const std::string& _p2)
{
    boost::filesystem::path p(_p1);
    return p.compare(_p2);
}

std::string JBaseFile::ModifyPath(std::string strPath, int index, std::string destStr)
{
    if(OPERATION_SYSTEM_TYPE == "LINUX")
    {
        std::list<std::string> str = JString::StrSplit(strPath,PATH_SPLIT);
        std::list<std::string>::iterator ite = str.begin();
        std::string tmp = "";
        int count = 0;
        for(;ite != str.end(); ++ite)
        {
            tmp += PATH_SPLIT;
            if(count == index)
            {
                tmp += destStr;
            }
            else
            {
                tmp += *ite;
            }
            ++count;
        }
        return tmp;
    }
}

bool JBaseFile::IsEqual(std::string strPath1,std::string strPath2,int _index)
{
    if(OPERATION_SYSTEM_TYPE == "LINUX")
    {
        std::list<std::string> str1 = JString::StrSplit(strPath1,PATH_SPLIT);
        std::list<std::string> str2 = JString::StrSplit(strPath2,PATH_SPLIT);       
        if(str1.size() != str2.size())
        {
            return false;
        }
        std::list<std::string>::iterator ite1 = str1.begin();
        std::list<std::string>::iterator ite2 = str2.begin();
        int index = 0;
        for(;ite1 != str1.end(); ++ite1)
        {
            if(index >= _index)
            {
                if(*ite1 != *ite2)
                {
                    return false;
                }
            }
            ++index;
            ++ite2;
        }
        return true;
    }
    return true;
}


std::list<std::string> JBaseFile::SplitPath(std::string _fileName)
{
    if(OPERATION_SYSTEM_TYPE == "LINUX")
    {
        return JString::StrSplit(_fileName,PATH_SPLIT);
    }
}

std::string JBaseFile::FileOrDir(std::string p)
{
    if(is_directory(p))
    {
        return "dir";
    }
    else
    {
        return "file";
    }
}